package xml.validations;

import java.util.ArrayList;
import java.util.List;

import xml.uidElements.entry.DataEntryElement;
import xml.uidElements.entry.AbstractDataItem;
import xml.uidElements.entry.DataItem;
import xml.uidElements.entry.DataItemSet;
import xml.uidElements.entry.AbstractStructure;
import xml.uidElements.entry.Structure;
import xml.uidElements.entry.StructureSet;

public class FinderInputElements {

	public List<DataEntryElement> findInput(String data) {

		data = data.replaceAll(" ", "");

		List<DataEntryElement> l = new ArrayList<DataEntryElement>();

		boolean ehSet = false;  //NOVO
		int minCardinality = 0;  //NOVO
		int maxCardinality = 0;   //NOVO
		
		String s = "";
		for (int i = 0; i < data.length(); i++) {

			char a = data.charAt(i);
			String b = "" + a;
			
			System.out.println(b);
			
			if (b.equals(",")) {

				if (!s.equals("")) {
					AbstractDataItem d;
					if (ehSet){
						d = new DataItemSet(s);
						((DataItemSet)d).setCardinality(minCardinality, maxCardinality);
					}	
					else
						d = new DataItem(s);

					l.add(d);
				}
				s = "";
				ehSet = false; //NOVO

			} else if (b.equals(":")) {

				AbstractDataItem d;
				if (ehSet){
					d = new DataItemSet(s);
					((DataItemSet)d).setCardinality(minCardinality, maxCardinality);
				}
				else 
					d = new DataItem(s);
				
				i = findDomain(d, i, data);
				l.add(d);
				s = "";
				ehSet = false; //NOVO
			
			} else if (b.equals("(")) {
 
				AbstractStructure st;
				if (ehSet){
					st = new StructureSet(s, "");
					((StructureSet)st).setCardinality(minCardinality, maxCardinality);
				}
				else
					st = new Structure(s, "");
				
				i = findData(st, i, data);
				l.add(st);
				s = "";
				ehSet = false; //NOVO
				
			} else if (b.equals(")")) {
				
				AbstractDataItem d;
				if (ehSet){
					d = new DataItemSet(s);
					((DataItemSet)d).setCardinality(minCardinality, maxCardinality);
				}
				else 
					d = new DataItem(s);
				l.add(d);
				s = "";
				ehSet = false; //NOVO

			} else {
				
				if (b.equals(".")){
					// vai procurar os conjuntos representados por ...
					String cardinality = "" + data.charAt(i+1) + data.charAt(i+2);
					if (cardinality.equals("..")){
						i = i+2;
						ehSet = true; //NOVO
						minCardinality = 0;  //NOVO
						maxCardinality = -1;   //NOVO
			
						s = "";
						System.out.println("Entrou para ver a cardinalidade");
					}
					
				}
				
				else {
					if (Character.isDigit(data.charAt(i))){

						ehSet = true; //NOVO

						//vai buscar a cardinalidade minima.
						String stringMinValue = "";
						while (Character.isDigit(data.charAt(i))){ 
							stringMinValue = stringMinValue + data.charAt(i);
							i++;
						}	
						i--;
						Integer minValue = Integer.parseInt(stringMinValue);
						minCardinality = minValue.intValue();
						
						//vai buscar a cardinalidade maxima. Se nao encontrar ".." , a cardinalidade maxima vai ser a minima tb.						
						String conjunto = "" + data.charAt(i+1) + data.charAt(i+2);
						if (conjunto.equals("..") && Character.isDigit(data.charAt(i+3)) ){
							i = i+3;
							String stringMaxValue = "";
							while (Character.isDigit(data.charAt(i))){ 
								stringMaxValue = stringMaxValue + data.charAt(i);
								i++;
							}	
							i--;
							Integer maxValue = Integer.parseInt(stringMaxValue);
							maxCardinality = maxValue.intValue();

						}
						else 						
							maxCardinality = minValue.intValue();   //NOVO

					}
				
				
					else {
						s = s + a;
					}
				}
			}
		}

		if (!s.equals("")) {
			DataItem d = new DataItem(s);
			l.add(d);
		}

		return l;
	}

	private int findData(AbstractStructure st, int i, String data) {
		String s = "";
		int j;
		
		boolean ehSetInTheStructure = false;  //NOVO
		int min = 0;  //NOVO
		int max = 0;   //NOVO

		
		for (j = i + 1; j < data.length(); j++) {
			char a = data.charAt(j);
			String b = "" + a;
			if (b.equals(")")) {
				if (!s.equals("")) {

					AbstractDataItem d;
					if (ehSetInTheStructure){
						d = new DataItemSet(s);
						((DataItemSet)d).setCardinality(min, max);
					}
					else 
						d = new DataItem(s);

					st.addDataEntry(d);
					ehSetInTheStructure = false; //NOVO
				
				}
				return j;
				
			} else if (b.equals(",")) {
				if (!s.equals("")) {

					AbstractDataItem d;
					if (ehSetInTheStructure){
						d = new DataItemSet(s);
						((DataItemSet)d).setCardinality(min, max);
					}
					else 
						d = new DataItem(s);

					st.addDataEntry(d);
					ehSetInTheStructure = false; //NOVO
				}
				s = "";
			} else if (b.equals(":")) {

				AbstractDataItem d;
				if (ehSetInTheStructure){
					d = new DataItemSet(s);
					((DataItemSet)d).setCardinality(min, max);
				}
				else 
					d = new DataItem(s);

				j = findDomain(d, j, data);
				st.addDataEntry(d);
				ehSetInTheStructure = false; //NOVO
				s = "";
			} else if (b.equals("(")) {

				AbstractStructure struct;
				if (ehSetInTheStructure){
					struct = new StructureSet(s, "");
					((StructureSet)struct).setCardinality(min, max);
				}
				else
					struct = new Structure(s, "");
				
				j = findData(struct, j, data);
				st.addDataEntry(struct);
				ehSetInTheStructure = false; //NOVO
				s = "";

			} else {

				if (b.equals(".")){
					String cardinality = "" + data.charAt(j+1) + data.charAt(j+2);
					if (cardinality.equals("..")){
						j = j+2;
						ehSetInTheStructure = true; //NOVO
						min = 0;  //NOVO
						max = -1;   //NOVO
			
						s = "";
						System.out.println("Entrou para ver a cardinalidade no outro nivel");
					}
					
				}
				
				else {
					
					if (Character.isDigit(data.charAt(j))){

						ehSetInTheStructure = true; //NOVO

						//vai buscar a cardinalidade minima.
						String stringMinValue = "";
						while (Character.isDigit(data.charAt(j))){ 
							stringMinValue = stringMinValue + data.charAt(j);
							j++;
						}	
						j--;
						Integer minValue = Integer.parseInt(stringMinValue);
						min = minValue.intValue();
						
						//vai buscar a cardinalidade maxima. Se nao encontrar ".." , a cardinalidade maxima vai ser a minima tb.						
						String conjunto = "" + data.charAt(j+1) + data.charAt(j+2);
						if (conjunto.equals("..") && Character.isDigit(data.charAt(j+3)) ){
							j = j+3;
							String stringMaxValue = "";
							while (Character.isDigit(data.charAt(j))){ 
								stringMaxValue = stringMaxValue + data.charAt(j);
								j++;
							}	
							j--;
							Integer maxValue = Integer.parseInt(stringMaxValue);
							max = maxValue.intValue();

						}
						else 						
							max = minValue.intValue();   //NOVO

					}
					
					else

						s = s + a;
				
				}
			}

		}
		if (!s.equals("")) {
			DataItem d = new DataItem(s);
			st.addDataEntry(d);
		}
		return j;
	}

	private int findDomain(AbstractDataItem d, int i, String data) {
		String s = "";
		int j;
		for (j = i + 1; j < data.length(); j++) {
			char a = data.charAt(j);
			String b = "" + a;
			if (b.equals(")")) {
				if (!s.equals(""))
					d.setDomain(s);
				return j - 1;
			} else if (b.equals(",")) {
				if (!s.equals(""))
					d.setDomain(s);
				return j;
			}
			s = s + b;

		}

		if (!s.equals("")) {
			d.setDomain(s);
		}

		return j;
	}

}
